import type { CanvasComponent } from '../stores/designStore';
import { exportHtml, exportMiniblinkProject } from './htmlExporter';
import type { ProjectExportData } from './codeGenerator';
import { cloneDeep } from 'lodash-es';
import axios from 'axios';
import { ComponentEnhancer } from './componentEnhancer';
import { HTMLExporter } from './htmlExporter';
import type { Component } from '@vue/runtime-core';

// 添加Electron类型声明
declare global {
  interface Window {
    electron?: {
      ipcRenderer: {
        invoke(channel: string, ...args: any[]): Promise<any>;
        send(channel: string, ...args: any[]): void;
        on(channel: string, func: (...args: any[]) => void): () => void;
        once(channel: string, func: (...args: any[]) => void): void;
      };
    };
    electronAPI?: {
      invoke(channel: string, ...args: any[]): Promise<any>;
      on(channel: string, callback: (...args: any[]) => void): () => void;
      once?(channel: string, func: (...args: any[]) => void): void;
    };
    nodeAPI?: {
      fs?: {
        readFileSync(path: string, options?: any): string | Buffer;
        writeFileSync(path: string, data: string | Buffer, options?: any): void;
        existsSync(path: string): boolean;
        mkdirSync(path: string, options?: { recursive?: boolean }): void;
        unlinkSync(path: string): void;
      };
      path?: {
        join(...paths: string[]): string;
        dirname(p: string): string;
        basename(p: string, ext?: string): string;
        extname(p: string): string;
        resolve(...paths: string[]): string;
      };
      process?: {
        cwd(): string;
        env: any;
        platform: string;
      };
    };
  }
}

// 导出选项接口
export interface ExportOptions {
  name?: string;
  components: CanvasComponent[];
  exportPath?: string;
  compatibilityMode?: boolean;
  includeSourceCode?: boolean;
}

// 导出结果接口
export interface ExportResult {
  success: boolean;
  message: string;
  filePath?: string;
}

/**
 * Miniblink 导出器
 * 提供 Miniblink 相关的导出功能
 */
export class MiniblinkExporter extends HTMLExporter {
  // Vue 3 CDN URL
  private static readonly VUE_CDN_URL = 'https://unpkg.com/vue@3/dist/vue.global.prod.js';
  
  // Element Plus CDN URLs
  private static readonly ELEMENT_PLUS_CSS_URL = 'https://unpkg.com/element-plus/dist/index.css';
  private static readonly ELEMENT_PLUS_JS_URL = 'https://unpkg.com/element-plus';
  
  /**
   * 准备 Miniblink 导出数据
   * @param projectData 项目数据
   * @returns 处理后的项目数据
   */
  static prepareExportData(projectData: ProjectExportData): ProjectExportData {
    // 深拷贝以避免修改原始数据
    const exportData = cloneDeep(projectData);
    
    // 只保留需要的模板
    exportData.templatesToRender = [
      { template: 'miniblink.html.ejs', output: 'index.html' }
    ];

    return exportData;
  }

  /**
   * 清理CSS字符串，移除可能导致PostCSS解析错误的内容
   * @param css CSS字符串
   * @returns 清理后的CSS字符串
   */
  private static cleanCssContent(css: string): string {
    // 移除@charset声明，这个声明在内联样式中可能导致问题
    return css.replace(/@charset\s+["']UTF-8["'];?/gi, '')
              .replace(/@charset\s+["']utf-8["'];?/gi, '')
              .trim();
  }

  /**
   * 获取外部库的代码
   * @returns 包含各种库代码的对象
   */
  static async fetchExternalLibraries(): Promise<{
    vueRuntime: string;
    elementPlusStyles: string;
    elementPlusRuntime: string;
  }> {
    try {
      // 并行请求库文件
      const [vueResponse, elementPlusStylesResponse, elementPlusRuntimeResponse] = await Promise.all([
        axios.get(this.VUE_CDN_URL),
        axios.get(this.ELEMENT_PLUS_CSS_URL),
        axios.get(this.ELEMENT_PLUS_JS_URL)
      ]);

      // 清理CSS内容，移除可能导致问题的部分
      const cleanedElementPlusStyles = this.cleanCssContent(elementPlusStylesResponse.data);

      return {
        vueRuntime: vueResponse.data,
        elementPlusStyles: cleanedElementPlusStyles,
        elementPlusRuntime: elementPlusRuntimeResponse.data
      };
    } catch (error) {
      console.error('获取外部库失败:', error);
      // 如果获取失败，返回CDN链接
      return {
        vueRuntime: `// 加载失败，请确保网络连接正常\n// 使用 CDN 链接代替\ndocument.write('<script src="${this.VUE_CDN_URL}"><\\/script>');`,
        elementPlusStyles: `/* 直接使用CDN引入样式 */\n@import url('${this.ELEMENT_PLUS_CSS_URL}');`,
        elementPlusRuntime: `// 加载失败，请确保网络连接正常\n// 使用 CDN 链接代替\ndocument.write('<script src="${this.ELEMENT_PLUS_JS_URL}"><\\/script>');`
      };
    }
  }

  /**
   * 准备导出数据
   * @param options 导出选项
   * @returns 准备好的导出数据
   */
  private prepareExportData(options: ExportOptions) {
    console.log('准备导出数据', options);
    
    // 获取自定义组件样式
    const componentStyles = this.getCustomComponentStyles();
    
    // 序列化并重新解析组件，确保移除不可序列化的属性
    const safeComponents = JSON.parse(JSON.stringify(options.components));
    
    // 不再使用rootComponent包装组件，直接使用原始组件数组
    const exportData = {
      projectName: options.name || 'EasyWindowApp',
      components: safeComponents, // 直接使用原始组件数组
      options: {
        exportPath: options.exportPath || '',
        compatibilityMode: options.compatibilityMode || false,
        includeSourceCode: options.includeSourceCode || false
      },
      componentStyles
    };
    
    console.log('准备好的导出数据', exportData);
    return exportData;
  }
  
  /**
   * 获取自定义组件样式
   * @returns 自定义组件样式对象
   */
  private getCustomComponentStyles() {
    return {
      // 按钮组件样式
      'el-button': {
        // ... existing code ...
      }
    };
  }

  /**
   * 简化组件数据，使其更轻量，更适合序列化
   * @param component 原始组件对象
   * @returns 简化后的组件对象
   */
  private simplifyComponent(component: any): any {
    // 基础数据结构检查
    if (!component || typeof component !== 'object') {
      return null;
    }
    
    // 创建一个新的简化对象
    const simplified: any = {
      id: component.id || `comp-${Math.random().toString(36).substr(2, 9)}`,
      type: component.type || 'div',
    };
    
    // 转换自定义组件类型为ElementPlus类型
    if (simplified.type && simplified.type.startsWith('ew-')) {
      simplified.type = simplified.type.replace('ew-', 'el-');
    }
    
    // 添加props（只保留基本类型）
    if (component.props) {
      simplified.props = {};
      Object.keys(component.props).forEach(key => {
        const value = component.props[key];
        const valueType = typeof value;
        
        // 只保留基本类型
        if (valueType === 'string' || valueType === 'number' || valueType === 'boolean' || value === null) {
          simplified.props[key] = value;
        } else if (Array.isArray(value)) {
          // 对于数组，过滤掉复杂对象
          simplified.props[key] = value.filter(item => {
            const itemType = typeof item;
            return itemType === 'string' || itemType === 'number' || itemType === 'boolean' || item === null;
          });
        }
      });
    }
    
    // 添加样式（只保留字符串和数字）
    if (component.style) {
      simplified.style = {};
      Object.keys(component.style).forEach(key => {
        const value = component.style[key];
        if (typeof value === 'string' || typeof value === 'number') {
          simplified.style[key] = value;
        }
      });
    }
    
    // 添加事件（只保留字符串）
    if (component.events) {
      simplified.events = {};
      Object.keys(component.events).forEach(key => {
        const value = component.events[key];
        if (typeof value === 'string') {
          simplified.events[key] = value;
        }
      });
    }
    
    // 递归处理子组件
    if (component.children && Array.isArray(component.children)) {
      simplified.children = component.children.map(child => this.simplifyComponent(child));
    }
    
    return simplified;
  }

  /**
   * 清理组件数据，移除不可序列化的属性
   * @param components 组件数组
   * @returns 清理后的可序列化组件数组
   */
  private sanitizeComponentsForIPC(components: any[]): any[] {
    try {
      // 先尝试使用JSON序列化再解析来移除不可序列化的属性
      const jsonString = JSON.stringify(components, (key, value) => {
        // 处理函数、Symbol等特殊类型
        if (typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
          return undefined;
        }
        // 处理特殊对象
        if (value instanceof Error) {
          return { message: value.message };
        }
        // 处理其他特殊类型，如Set、Map等
        if (value instanceof Set) {
          return [...value];
        }
        if (value instanceof Map) {
          return Object.fromEntries(value);
        }
        return value;
      });
      return JSON.parse(jsonString);
    } catch (error) {
      console.error('组件序列化失败，执行手动清理:', error);
      
      // 手动深度清理组件数据
      return this.deepCleanComponents(components);
    }
  }
  
  /**
   * 深度清理组件数据，处理所有不可序列化的属性
   * @param components 要清理的组件数组
   * @returns 清理后的组件数组
   */
  private deepCleanComponents(components: any[]): any[] {
    if (!Array.isArray(components)) {
      console.warn('deepCleanComponents接收到非数组数据:', typeof components);
      return [];
    }

    return components.map(comp => {
      // 如果组件为null或undefined，直接返回null
      if (comp == null) return null;
      
      // 创建一个新的干净组件对象
      const cleanComp: any = {};
      
      // 只复制基本属性
      const basicProps = ['id', 'type', 'name', 'visible'];
      basicProps.forEach(prop => {
        if (comp[prop] !== undefined) {
          cleanComp[prop] = comp[prop];
        }
      });

      // 特殊处理props对象
      if (comp.props) {
        cleanComp.props = {};
        // 只复制可序列化的prop值
        Object.keys(comp.props).forEach(key => {
          try {
            // 不直接使用JSON.stringify，而是先检查类型
            const value = comp.props[key];
            const valueType = typeof value;
            
            // 对基本类型直接复制
            if (valueType === 'string' || valueType === 'number' || valueType === 'boolean' || value === null) {
              cleanComp.props[key] = value;
            } 
            // 对数组进行过滤处理
            else if (Array.isArray(value)) {
              cleanComp.props[key] = value.map(item => {
                const itemType = typeof item;
                if (itemType === 'string' || itemType === 'number' || itemType === 'boolean' || item === null) {
                  return item;
                }
                // 复杂对象转为字符串
                if (itemType === 'object' && item !== null) {
                  try {
                    return JSON.stringify(item);
                  } catch (e) {
                    return `[复杂对象]`;
                  }
                }
                return null;
              }).filter(Boolean);
            }
            // 对象类型
            else if (valueType === 'object' && value !== null) {
              try {
                // 尝试转为纯对象
                const safeObj = {};
                Object.keys(value).forEach(k => {
                  const v = value[k];
                  const vType = typeof v;
                  if (vType === 'string' || vType === 'number' || vType === 'boolean' || v === null) {
                    safeObj[k] = v;
                  } else {
                    // 跳过不安全的值
                  }
                });
                cleanComp.props[key] = safeObj;
              } catch (e) {
                // 忽略无法处理的对象
              }
            }
            // 其他类型跳过
          } catch (e) {
            console.warn(`清理属性 ${key} 时出错:`, e);
          }
        });
      }

      // 特殊处理style对象
      if (comp.style) {
        cleanComp.style = {};
        Object.keys(comp.style).forEach(key => {
          const value = comp.style[key];
          const valueType = typeof value;
          
          // 只包含安全的样式值
          if (valueType === 'string' || valueType === 'number' || value === null) {
            cleanComp.style[key] = value;
          }
        });
      }

      // 特殊处理events对象
      if (comp.events) {
        cleanComp.events = {};
        Object.keys(comp.events).forEach(key => {
          const value = comp.events[key];
          // 事件应该是字符串格式
          if (typeof value === 'string') {
            cleanComp.events[key] = value;
          } else {
            // 如果不是字符串，尝试转换或使用空字符串
            try {
              cleanComp.events[key] = String(value);
            } catch (e) {
              cleanComp.events[key] = '';
            }
          }
        });
      }

      // 递归处理子组件
      if (comp.children && Array.isArray(comp.children)) {
        cleanComp.children = this.deepCleanComponents(comp.children);
      }

      return cleanComp;
    }).filter(Boolean); // 过滤掉null值
  }

  /**
   * 导出项目
   * @param param0 导出参数
   * @returns 导出结果
   */
  async export({ 
    components, 
    productName = 'UI Generated by Easy Window',
    savePath,
    canvasSize = { width: 800, height: 600 },
    canvasStyle = { 
      backgroundColor: '#ffffff', 
      borderWidth: 1, 
      borderStyle: 'solid', 
      borderColor: '#cccccc', 
      borderRadius: 0 
    },
    skipBrowserDownload = false
  }: {
    components: any[],
    productName?: string,
    savePath: string,
    canvasSize?: { width: number, height: number },
    canvasStyle?: { 
      backgroundColor?: string, 
      borderWidth?: number, 
      borderStyle?: string, 
      borderColor?: string, 
      borderRadius?: number 
    },
    skipBrowserDownload?: boolean
  }) {
    console.log(`开始导出Miniblink HTML，保存路径: ${savePath}`);
    
    try {
      // 检查环境
      const isElectron = !!(
        window && 
        (
          (window.electron && window.electron.ipcRenderer) || 
          (window.electronAPI && window.electronAPI.invoke)
        )
      );
      
      if (!isElectron) {
        console.warn('不在Electron环境中，回退到浏览器模拟导出');
        return this.mockExportForDevelopment({
          name: productName,
          components,
          exportPath: savePath
        });
      }
      
      // 确定是否可以访问IPC渲染器
      const ipcRenderer = window.electron?.ipcRenderer || window.electronAPI;
      
      if (!ipcRenderer || !ipcRenderer.invoke) {
        console.error('无法访问IPC渲染器');
        return { success: false, message: '无法访问IPC渲染器' };
      }
      
      // 获取画布样式
      const canvasEl = document.querySelector('.canvas-content') as HTMLElement;
      let resolvedCanvasStyle = { ...canvasStyle };
      
      if (canvasEl) {
        // 从DOM中获取实际的画布样式
        const computedStyle = window.getComputedStyle(canvasEl);
        resolvedCanvasStyle = {
          backgroundColor: computedStyle.backgroundColor || canvasStyle.backgroundColor,
          borderWidth: parseInt(computedStyle.borderWidth) || canvasStyle.borderWidth,
          borderStyle: computedStyle.borderStyle || canvasStyle.borderStyle,
          borderColor: computedStyle.borderColor || canvasStyle.borderColor,
          borderRadius: parseInt(computedStyle.borderRadius) || canvasStyle.borderRadius
        };
        
        console.log('从DOM获取到的画布样式:', resolvedCanvasStyle);
      }
      
      // 尝试直接传递组件数据到主进程
      try {
        console.log('尝试直接导出，组件数量:', components.length);
        
        // 使用直接导出处理
        const result = await ipcRenderer.invoke('handle-miniblink-direct-export', {
          basicData: {
            outputPath: savePath,
            projectName: productName,
            canvasWidth: canvasSize.width,
            canvasHeight: canvasSize.height,
            canvasBackgroundColor: resolvedCanvasStyle.backgroundColor,
            canvasBorderWidth: resolvedCanvasStyle.borderWidth,
            canvasBorderStyle: resolvedCanvasStyle.borderStyle,
            canvasBorderColor: resolvedCanvasStyle.borderColor,
            canvasBorderRadius: resolvedCanvasStyle.borderRadius
          },
          components: this.sanitizeComponentsForIPC(components)
        });
        
        console.log('导出结果:', result);
        return {
          success: result.success,
          message: result.message || (result.success ? '导出成功' : '导出失败'),
          filePath: result.filePath
        };
      } catch (exportError) {
        console.error('导出调用失败，尝试空导出:', exportError);
        
        // 尝试空导出
        try {
          const emptyResult = await ipcRenderer.invoke('handle-miniblink-empty-export', {
            outputPath: savePath,
            projectName: productName,
            canvasWidth: canvasSize.width,
            canvasHeight: canvasSize.height,
            canvasBackgroundColor: resolvedCanvasStyle.backgroundColor,
            canvasBorderWidth: resolvedCanvasStyle.borderWidth,
            canvasBorderStyle: resolvedCanvasStyle.borderStyle,
            canvasBorderColor: resolvedCanvasStyle.borderColor,
            canvasBorderRadius: resolvedCanvasStyle.borderRadius
          });
          
          return {
            success: emptyResult.success,
            message: `${emptyResult.message} (组件数据无法序列化)`,
            filePath: emptyResult.filePath
          };
        } catch (finalError) {
          console.error('所有导出尝试都失败:', finalError);
          return {
            success: false,
            message: `导出失败: ${finalError.message || String(finalError)}`
          };
        }
      }
    } catch (error) {
      console.error('导出过程中出错:', error);
      return {
        success: false,
        message: `导出过程中出错: ${error.message || String(error)}`
      };
    }
  }
  
  /**
   * 导出 Vue3 项目文件
   * @param options 导出选项
   * @returns 导出结果
   */
  async exportProjectWithVue3(options: ExportOptions): Promise<ExportResult> {
    console.log('开始导出 Vue3 项目', options);
    
    // 增强对Electron环境的检测，与exportProject保持一致
    const isElectron = !!(
      window && 
      (
        (window.electron && window.electron.ipcRenderer) || 
        (window.electronAPI && window.electronAPI.invoke)
      )
    );
    console.log('是否在Electron环境中:', isElectron, 
      '存在可用的electron.ipcRenderer:', !!(window.electron && window.electron.ipcRenderer), 
      '存在可用的electronAPI.invoke:', !!(window.electronAPI && window.electronAPI.invoke));
    
    if (isElectron) {
      try {
        // 准备导出数据
        const exportData = this.prepareExportData(options);
        
        // 调用 Electron 主进程导出功能 - 优先使用window.electron，如果不存在则使用window.electronAPI
        let result;
        // 使用handle-export-for-miniblink处理函数，添加vue3参数标识
        if (window.electron && window.electron.ipcRenderer) {
          const modifiedData = { ...exportData, vue3Mode: true };
          result = await window.electron.ipcRenderer.invoke('handle-export-for-miniblink', modifiedData);
          console.log('使用window.electron.ipcRenderer调用Vue3导出，结果:', result);
        } else if (window.electronAPI) {
          const modifiedData = { ...exportData, vue3Mode: true };
          result = await window.electronAPI.invoke('handle-export-for-miniblink', modifiedData);
          console.log('使用window.electronAPI调用Vue3导出，结果:', result);
        } else {
          throw new Error('Electron IPC渲染器未找到');
        }
        
        console.log('Vue3 导出结果', result);
        
        if (!result) {
          console.error('Vue3导出返回了空结果');
          return {
            success: false,
            message: 'Vue3导出返回了空结果，请检查主进程处理程序'
          };
        }
        
        return {
          success: !!result.success,
          message: result.message || (result.success ? 'Vue3 导出成功' : 'Vue3 导出失败'),
          filePath: result.filePath
        };
      } catch (error: any) {
        console.error('Vue3 导出错误', error);
        return {
          success: false,
          message: `Vue3 导出失败: ${error.message || '未知错误'}`
        };
      }
    } else {
      // 非 Electron 环境使用模拟导出
      return this.mockExportForDevelopment(options);
    }
  }
  
  /**
   * 开发环境下模拟导出功能
   * @param options 导出选项
   * @returns 模拟的导出结果
   */
  private async mockExportForDevelopment(options: ExportOptions): Promise<ExportResult> {
    console.log('开发环境模拟导出', options);
    
    try {
      // 模拟导出延迟
      console.log('模拟处理数据...');
      await new Promise(resolve => setTimeout(resolve, 500));
      
      // 获取示例HTML模板
      const htmlTemplate = this.generateMockTemplate(options);
      
      // 在控制台显示生成的HTML
      console.log('生成的HTML模板长度:', htmlTemplate.length);
      
      // 浏览器环境 - 使用下载API
      console.log('使用浏览器API创建下载链接');
      try {
        const blob = new Blob([htmlTemplate], { type: 'text/html' });
        const url = URL.createObjectURL(blob);
        
        // 创建下载链接
        const link = document.createElement('a');
        link.href = url;
        link.download = 'miniblink_export.html';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        
        // 释放URL对象
        setTimeout(() => URL.revokeObjectURL(url), 100);
        
        return {
          success: true,
          message: `浏览器环境导出成功，已下载HTML文件，组件数量: ${options.components.length}`,
          filePath: 'miniblink_export.html'
        };
      } catch (downloadError) {
        console.error('创建下载链接失败:', downloadError);
        return {
          success: false,
          message: `浏览器下载失败: ${downloadError instanceof Error ? downloadError.message : String(downloadError)}`
        };
      }
    } catch (error) {
      console.error('模拟导出失败:', error);
      return {
        success: false,
        message: `模拟导出失败: ${error instanceof Error ? error.message : String(error)}`
      };
    }
  }
  
  /**
   * 生成模拟HTML模板
   * @param options 导出选项
   * @returns HTML模板字符串
   */
  private generateMockTemplate(options: ExportOptions): string {
    return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${options.name || 'Miniblink UI'}</title>
  <!-- Vue 3 库 -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  
  <!-- Element Plus 样式和库 -->
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  <script src="https://unpkg.com/element-plus"></script>
  
  <style>
    body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
    .container { max-width: 800px; margin: 0 auto; }
    .header { text-align: center; margin-bottom: 30px; }
    .component-list { border: 1px solid #eee; padding: 15px; border-radius: 5px; }
    .component-item { margin-bottom: 10px; padding: 10px; background: #f9f9f9; border-radius: 3px; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>模拟Miniblink导出</h1>
      <p>这是在浏览器环境下生成的模拟文件</p>
    </div>
    <div class="component-list">
      <h2>组件列表：</h2>
      ${options.components.map(comp => 
        `<div class="component-item">
          <strong>类型:</strong> ${comp.type}, 
          <strong>ID:</strong> ${comp.id}
        </div>`
      ).join('')}
    </div>
    <p>导出时间: ${new Date().toLocaleString()}</p>
  </div>
  
  <script>
    // 组件数据
    window.appState = {
      components: ${JSON.stringify(options.components)},
      componentStates: {},
      errorMessage: null,
      isLoading: false
    };
    
    // 初始化Vue应用
    document.addEventListener('DOMContentLoaded', function() {
      const app = Vue.createApp({
        template: \`<div class="app-container">
          <h3>Vue 3 应用已加载</h3>
          <el-button type="primary">Element Plus 按钮</el-button>
          <p>组件总数: {{ componentCount }}</p>
        </div>\`,
        computed: {
          componentCount() {
            return window.appState.components.length;
          }
        }
      });
      app.use(ElementPlus);
      app.mount('#app-root');
    });
  </script>
  
  <div id="app-root"></div>
</body>
</html>`;
  }

  /**
   * 获取易语言示例代码
   * @param htmlPath HTML文件路径
   * @returns 易语言示例代码
   */
  static getECodeExample(htmlPath: string): string {
    return `.版本 2

.程序集 窗口程序集

.子程序 _启动子程序, 整数型
.局部变量 窗口, 整数型
.局部变量 浏览器, 整数型

// 创建窗口
窗口 = 创建窗口 ("Miniblink 测试程序", , , 800, 600)

// 创建浏览器
浏览器 = 创建浏览器 (窗口, "${htmlPath}")

// 注册事件
浏览器_注册事件 (浏览器, "app:ready", "应用就绪")
浏览器_注册事件 (浏览器, "component:click", "组件点击")
浏览器_注册事件 (浏览器, "component:change", "组件变化")

// 显示窗口
显示窗口 (窗口)

返回 (0)

.子程序 应用就绪, 整数型, 文本型 数据
调试输出 ("应用已就绪: " ＋ 数据)
返回 (0)

.子程序 组件点击, 整数型, 文本型 数据
调试输出 ("组件点击: " ＋ 数据)
返回 (0)

.子程序 组件变化, 整数型, 文本型 数据
调试输出 ("组件变化: " ＋ 数据)
返回 (0)`;
  }

  /**
   * 获取 C# 示例代码
   * @param htmlPath HTML文件路径
   * @returns C# 示例代码
   */
  static getCSharpExample(htmlPath: string): string {
    return `using System;
using System.Windows.Forms;
using MiniblinkNet;

namespace MiniblinkTest
{
    public partial class MainForm : Form
    {
        private WebView webView;

        public MainForm()
        {
            InitializeComponent();
            
            // 创建 WebView
            webView = new WebView();
            webView.Dock = DockStyle.Fill;
            this.Controls.Add(webView);
            
            // 注册事件处理
            webView.OnLoadUrl += WebView_OnLoadUrl;
            webView.OnDocumentReady += WebView_OnDocumentReady;
            
            // 加载 HTML 文件
            webView.LoadUrl("${htmlPath}");
        }

        private void WebView_OnLoadUrl(object sender, LoadUrlEventArgs e)
        {
            Console.WriteLine("开始加载: " + e.Url);
        }

        private void WebView_OnDocumentReady(object sender, DocumentReadyEventArgs e)
        {
            Console.WriteLine("文档加载完成: " + e.Url);
            
            // 注册自定义事件处理
            webView.InvokeScript(@"
                window.miniBridge.on('app:ready', function(data) {
                    window.external.notifyEvent('app:ready', JSON.stringify(data));
                });
                
                window.miniBridge.on('component:click', function(data) {
                    window.external.notifyEvent('component:click', JSON.stringify(data));
                });
                
                window.miniBridge.on('component:change', function(data) {
                    window.external.notifyEvent('component:change', JSON.stringify(data));
                });
            ");
            
            // 添加 JS 回调
            webView.BindFunction("notifyEvent", false, (WebView sender, IntPtr param, MiniblinkNet.jsValue[] args) => {
                if (args.Length >= 2)
                {
                    string eventName = args[0].ToString();
                    string eventData = args[1].ToString();
                    Console.WriteLine($"事件: {eventName}, 数据: {eventData}");
                }
                return MiniblinkNet.jsValue.Undefined();
            });
        }
    }
}`;
  }

  /**
   * 获取符合易语言Miniblink模块规范的易语言代码
   * @param htmlPath HTML文件路径
   * @returns 易语言特定代码
   */
  static getEasyLangSpecificCode(htmlPath: string): string {
    return `.版本 2

.程序集 窗口程序集

.子程序 _启动子程序, 整数型
.局部变量 窗口, 整数型
.局部变量 浏览器, 整数型

// 创建窗口
窗口 = 创建窗口 ("Miniblink 测试程序", , , 800, 600)

// 绑定Miniblink
浏览器 = MB浏览框.绑定 (窗口)

// 设置事件回调
MB浏览框.事件_文档就绪 (浏览器_文档就绪, 0)
MB浏览框.事件_载入完成 (浏览器_载入完成, 0)

// 加载HTML文件
MB浏览框.载入文件 ("${htmlPath}")

// 显示窗口
显示窗口 (窗口)

返回 (0)

.子程序 浏览器_文档就绪, 整数型, 整数型 浏览器, 整数型 用户数据
// 运行JavaScript注册事件监听
MB浏览框.运行JS ("
  if (window.miniBridge) {
    window.miniBridge.on('app:ready', function(data) {
      window.external.notifyEvent('app:ready', JSON.stringify(data));
    });
    
    window.miniBridge.on('component:click', function(data) {
      window.external.notifyEvent('component:click', JSON.stringify(data));
    });
    
    window.miniBridge.on('component:change', function(data) {
      window.external.notifyEvent('component:change', JSON.stringify(data));
    });
  } else {
    console.error('miniBridge not found');
  }
")

// 绑定JS回调函数
JS绑定函数 ("notifyEvent", JS事件处理, 2)

返回 (0)

.子程序 浏览器_载入完成, 整数型, 整数型 浏览器, 整数型 用户数据, 整数型 URL, 整数型 载入返回, 整数型 失败原因
调试输出 ("页面载入完成")
返回 (0)

.子程序 JS事件处理, 长整数型, 整数型 JS执行状态
.局部变量 事件名, 文本型
.局部变量 事件数据, 文本型

// 获取事件名称和数据
事件名 = JS取参数_文本 (JS执行状态, 0)
事件数据 = JS取参数_文本 (JS执行状态, 1)

// 根据事件名称处理不同事件
如果 (事件名 = "app:ready")
    调试输出 ("应用就绪事件: " + 事件数据)
否则如果 (事件名 = "component:click") 
    调试输出 ("组件点击事件: " + 事件数据)
否则如果 (事件名 = "component:change")
    调试输出 ("组件变化事件: " + 事件数据)
结束如果

返回 (JS未定义 ())`;
  }

  /**
   * 获取适配易语言Miniblink模块的更简单示例代码
   * @param htmlPath HTML文件路径
   * @returns 简化的易语言示例代码
   */
  static getSimpleECodeExample(htmlPath: string): string {
    return `.版本 2

.程序集 窗口程序集

.子程序 _启动子程序, 整数型
.局部变量 窗口, 整数型
.局部变量 浏览器, 整数型

// 创建窗口
窗口 = 创建窗口 ("Miniblink 测试程序", , , 800, 600)

// 创建浏览器
浏览器 = MB浏览框.绑定 (窗口)

// 载入HTML文件
MB浏览框.载入文件 ("${htmlPath}")

// 显示窗口
显示窗口 (窗口)

返回 (0)`;
  }

  /**
   * 紧急回退导出，用于临时文件方法失败时
   * @param exportPath 输出路径
   * @param components 组件数据
   * @param projectName 项目名称
   * @param canvasSize 画布尺寸
   * @returns 导出结果
   */
  private async fallbackToDirectExport(
    exportPath: string,
    components: any[],
    projectName: string,
    canvasSize?: { width: number; height: number }
  ): Promise<ExportResult> {
    console.log('使用直接导出方式回退');
    try {
      // 尝试创建极简化版本的组件数据
      const minimalComponents = components.map(comp => ({
        id: comp.id || '',
        type: comp.type || '',
        name: comp.name || ''
      }));
      
      // 创建最简单的导出数据
      const basicData = {
        outputPath: exportPath,
        components: minimalComponents,
        projectName: projectName || 'MiniblinkExport',
        canvasSize: {
          width: Number(canvasSize?.width) || 800,
          height: Number(canvasSize?.height) || 600
        }
      };
      
      // 通过stringifyReplacer处理数据，移除循环引用和不可序列化的内容
      const safeData = JSON.parse(JSON.stringify(basicData, (key, value) => {
        // 忽略函数和Symbol
        if (typeof value === 'function' || typeof value === 'symbol') {
          return undefined;
        }
        return value;
      }));
      
      // 尝试直接IPC调用
      try {
        const ipcRenderer = window.electron?.ipcRenderer || window.electronAPI;
        if (ipcRenderer) {
          const result = await ipcRenderer.invoke('handle-miniblink-html-export', safeData);
          return result;
        }
      } catch (ipcError) {
        console.error('直接IPC调用失败，使用HTML生成回退:', ipcError);
      }
      
      // 最后回退到emergencyFallbackExport
      return this.emergencyFallbackExport(exportPath, minimalComponents, projectName);
    } catch (fallbackError) {
      console.error('回退导出失败:', fallbackError);
      // 最终回退 - 生成最简单的HTML
      return this.emergencyFallbackExport(exportPath, [], projectName);
    }
  }

  /**
   * 紧急回退导出方案，用于处理IPC通信或序列化失败的情况
   * @param outputPath 输出路径
   * @param components 简化后的组件数据
   * @param projectName 项目名称
   * @returns 导出结果
   */
  private async emergencyFallbackExport(
    outputPath: string, 
    components: any[] = [], 
    projectName: string = 'MiniblinkExport'
  ): Promise<ExportResult> {
    console.log('执行紧急回退导出方案');
    try {
      // 生成一个最简单的HTML文件
      const fallbackHtml = this.generateEmergencyHTML(projectName, components);
      
      // 浏览器环境下尝试下载
      if (!window.electronAPI && !window.electron) {
        try {
          // 尝试下载
          const blob = new Blob([fallbackHtml], { type: 'text/html' });
          const url = URL.createObjectURL(blob);
          
          const link = document.createElement('a');
          link.href = url;
          link.download = outputPath.split('/').pop() || 'miniblink_export.html';
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          
          // 清理URL
          setTimeout(() => URL.revokeObjectURL(url), 100);
          
          return {
            success: true,
            message: '使用紧急回退方案导出成功',
            filePath: link.download
          };
        } catch (downloadError) {
          console.error('紧急回退下载失败:', downloadError);
          return {
            success: false,
            message: `紧急回退方案导出失败: ${downloadError instanceof Error ? downloadError.message : String(downloadError)}`
          };
        }
      }
      
      // Electron环境 - 尝试直接写入文件
      try {
        // 创建一个简单的导出函数，不依赖IPC
        let success = false;
        let message = '紧急回退方案执行失败';
        
        // 尝试使用window.nodeAPI直接写入文件
        if (window.nodeAPI?.fs && window.nodeAPI?.path) {
          // 确保目录存在
          const dirPath = outputPath.substring(0, outputPath.lastIndexOf('/'));
          
          if (dirPath && !window.nodeAPI.fs.existsSync(dirPath)) {
            window.nodeAPI.fs.mkdirSync(dirPath, { recursive: true });
          }
          
          // 写入文件
          window.nodeAPI.fs.writeFileSync(outputPath, fallbackHtml, 'utf-8');
          success = true;
          message = '使用紧急回退方案导出成功';
        } else {
          // 最后一次机会 - 尝试使用简单的IPC调用
          if (window.electron?.ipcRenderer) {
            // 发送一个极简数据到主进程
            const basicData = {
              html: fallbackHtml,
              path: outputPath
            };
            
            try {
              // 尝试保存文件
              const saveResult = await window.electron.ipcRenderer.invoke('save-file', {
                content: fallbackHtml,
                fileName: outputPath.split('/').pop() || 'miniblink_export.html'
              });
              
              success = saveResult.success;
              message = saveResult.message || '紧急回退方案导出完成';
              outputPath = saveResult.filePath || outputPath;
            } catch (saveError) {
              console.error('紧急保存调用失败:', saveError);
              success = false;
              message = `紧急保存调用失败: ${saveError instanceof Error ? saveError.message : String(saveError)}`;
            }
          }
        }
        
        return {
          success,
          message,
          filePath: success ? outputPath : undefined
        };
      } catch (writeError) {
        console.error('紧急写入文件失败:', writeError);
        return {
          success: false,
          message: `紧急写入文件失败: ${writeError instanceof Error ? writeError.message : String(writeError)}`
        };
      }
    } catch (error) {
      console.error('紧急回退导出方案执行失败:', error);
      return {
        success: false,
        message: `紧急回退导出方案执行失败: ${error instanceof Error ? error.message : String(error)}`
      };
    }
  }
  
  /**
   * 生成紧急回退HTML模板 - 使用最简单的结构，避免任何可能的错误
   * @param projectName 项目名称
   * @param components 组件数据
   * @returns HTML字符串
   */
  private generateEmergencyHTML(projectName: string, components: any[] = []): string {
    // 由于这是紧急回退方案，我们使用最简单的HTML结构
    return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${projectName || 'Miniblink UI'}</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
  <script src="https://unpkg.com/element-plus"></script>
  <style>
    body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
    .container { max-width: 800px; margin: 0 auto; padding: 20px; }
    .header { text-align: center; margin-bottom: 30px; }
    .component-list { border: 1px solid #eee; padding: 15px; border-radius: 5px; }
    .ui-container { margin-top: 20px; padding: 20px; border: 1px solid #ddd; border-radius: 4px; background: #f9f9f9; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>${projectName || 'Miniblink UI'}</h1>
      <p>由 Easy Window 导出 (紧急回退方案)</p>
    </div>
    
    <div class="component-list">
      <h2>组件列表：</h2>
      ${components.map(comp => 
        `<div><strong>${comp.type || '未知类型'}</strong> (ID: ${comp.id || '无ID'})</div>`
      ).join('') || '<div>无组件数据</div>'}
    </div>
    
    <div class="ui-container" id="app"></div>
  </div>
  
  <script>
    // 初始化Vue应用
    document.addEventListener('DOMContentLoaded', function() {
      const app = Vue.createApp({
        template: \`
          <div class="app-container">
            <h3>应用已就绪</h3>
            <el-button type="primary">测试按钮</el-button>
          </div>
        \`,
        setup() {
          // 回调通知机制
          window.MiniblinkCallback = function(event, data) {
            console.log('MiniblinkCallback:', event, data);
            if (window.external && window.external.notify) {
              try {
                window.external.notify(JSON.stringify({event, data}));
              } catch (e) {
                console.error('外部回调失败:', e);
              }
            }
          };
          
          // 组件数据
          const components = ${JSON.stringify(components, null, 2)};
          
          // 通知应用已就绪
          setTimeout(() => {
            if (window.MiniblinkCallback) {
              window.MiniblinkCallback('app:ready', {components});
            }
          }, 500);
          
          return {};
        }
      });
      
      app.use(ElementPlus);
      app.mount('#app');
    });
  </script>
</body>
</html>`;
  }
}

export async function exportToMiniblinkHTML({ 
  components,
  productName,
  savePath,
  canvasSize
}: {
  components: Component[],
  productName: string,
  savePath: string,
  canvasSize?: { width: number, height: number }
}) {
  const fs = require('fs');
  const ejs = require('ejs');
  const path = require('path');
  
  const htmlExporter = new HTMLExporter();
  const templatePath = path.resolve(__dirname, '../templates/miniblink.html.ejs');
  const templateContent = fs.readFileSync(templatePath, 'utf-8');
  
  // 读取Vue3 Runtime
  const vueRuntime = fs.readFileSync(path.resolve(__dirname, '../vendor/vue.global.js'), 'utf-8');
  
  // 这里我们假设组件数据已经是准备好的格式
  const renderedHTML = ejs.render(templateContent, {
    components,
    productName: productName || 'UI Generated by Easy Window',
    vueRuntime,
    canvasSize: canvasSize || { width: 800, height: 600 }
  });
  
  // 保存HTML文件
  fs.writeFileSync(savePath, renderedHTML, 'utf-8');
  
  return {
    success: true,
    filePath: savePath
  };
}